#include <stdio.h>
#include "csi_math.h"

#define TAP_NUM  28
#define FIR_SIZE 320

static q15_t src[FIR_SIZE] = {
    0x0000, 0x5e22, 0x3b17, 0xf7bc, 0x0df3, 0x3333, 0x0df3, 0xf7bc,
    0x3b17, 0x5e22, 0x0000, 0xa1de, 0xc4e9, 0x0844, 0xf20d, 0xcccd,
    0xf20d, 0x0844, 0xc4e9, 0xa1de, 0x0000, 0x5e22, 0x3b17, 0xf7bc,
    0x0df3, 0x3333, 0x0df3, 0xf7bc, 0x3b17, 0x5e22, 0x0000, 0xa1de,
    0xc4e9, 0x0844, 0xf20d, 0xcccd, 0xf20d, 0x0844, 0xc4e9, 0xa1de,
    0x0000, 0x5e22, 0x3b17, 0xf7bc, 0x0df3, 0x3333, 0x0df3, 0xf7bc,
    0x3b17, 0x5e22, 0x0000, 0xa1de, 0xc4e9, 0x0844, 0xf20d, 0xcccd,
    0xf20d, 0x0844, 0xc4e9, 0xa1de, 0x0000, 0x5e22, 0x3b17, 0xf7bc,
    0x0df3, 0x3333, 0x0df3, 0xf7bc, 0x3b17, 0x5e22, 0x0000, 0xa1de,
    0xc4e9, 0x0844, 0xf20d, 0xcccd, 0xf20d, 0x0844, 0xc4e9, 0xa1de,
    0x0000, 0x5e22, 0x3b17, 0xf7bc, 0x0df3, 0x3333, 0x0df3, 0xf7bc,
    0x3b17, 0x5e22, 0x0000, 0xa1de, 0xc4e9, 0x0844, 0xf20d, 0xcccd,
    0xf20d, 0x0844, 0xc4e9, 0xa1de, 0x0000, 0x5e22, 0x3b17, 0xf7bc,
    0x0df3, 0x3333, 0x0df3, 0xf7bc, 0x3b17, 0x5e22, 0x0000, 0xa1de,
    0xc4e9, 0x0844, 0xf20d, 0xcccd, 0xf20d, 0x0844, 0xc4e9, 0xa1de,
    0x0000, 0x5e22, 0x3b17, 0xf7bc, 0x0df3, 0x3333, 0x0df3, 0xf7bc,
    0x3b17, 0x5e22, 0x0000, 0xa1de, 0xc4e9, 0x0844, 0xf20d, 0xcccd,
    0xf20d, 0x0844, 0xc4e9, 0xa1de, 0x0000, 0x5e22, 0x3b17, 0xf7bc,
    0x0df3, 0x3333, 0x0df3, 0xf7bc, 0x3b17, 0x5e22, 0x0000, 0xa1de,
    0xc4e9, 0x0844, 0xf20d, 0xcccd, 0xf20d, 0x0844, 0xc4e9, 0xa1de,
    0x0000, 0x5e22, 0x3b17, 0xf7bc, 0x0df3, 0x3333, 0x0df3, 0xf7bc,
    0x3b17, 0x5e22, 0x0000, 0xa1de, 0xc4e9, 0x0844, 0xf20d, 0xcccd,
    0xf20d, 0x0844, 0xc4e9, 0xa1de, 0x0000, 0x5e22, 0x3b17, 0xf7bc,
    0x0df3, 0x3333, 0x0df3, 0xf7bc, 0x3b17, 0x5e22, 0x0000, 0xa1de,
    0xc4e9, 0x0844, 0xf20d, 0xcccd, 0xf20d, 0x0844, 0xc4e9, 0xa1de,
    0x0000, 0x5e22, 0x3b17, 0xf7bc, 0x0df3, 0x3333, 0x0df3, 0xf7bc,
    0x3b17, 0x5e22, 0x0000, 0xa1de, 0xc4e9, 0x0844, 0xf20d, 0xcccd,
    0xf20d, 0x0844, 0xc4e9, 0xa1de, 0x0000, 0x5e22, 0x3b17, 0xf7bc,
    0x0df3, 0x3333, 0x0df3, 0xf7bc, 0x3b17, 0x5e22, 0x0000, 0xa1de,
    0xc4e9, 0x0844, 0xf20d, 0xcccd, 0xf20d, 0x0844, 0xc4e9, 0xa1de,
    0x0000, 0x5e22, 0x3b17, 0xf7bc, 0x0df3, 0x3333, 0x0df3, 0xf7bc,
    0x3b17, 0x5e22, 0x0000, 0xa1de, 0xc4e9, 0x0844, 0xf20d, 0xcccd,
    0xf20d, 0x0844, 0xc4e9, 0xa1de, 0x0000, 0x5e22, 0x3b17, 0xf7bc,
    0x0df3, 0x3333, 0x0df3, 0xf7bc, 0x3b17, 0x5e22, 0x0000, 0xa1de,
    0xc4e9, 0x0844, 0xf20d, 0xcccd, 0xf20d, 0x0844, 0xc4e9, 0xa1de,
    0x0000, 0x5e22, 0x3b17, 0xf7bc, 0x0df3, 0x3333, 0x0df3, 0xf7bc,
    0x3b17, 0x5e22, 0x0000, 0xa1de, 0xc4e9, 0x0844, 0xf20d, 0xcccd,
    0xf20d, 0x0844, 0xc4e9, 0xa1de, 0x0000, 0x5e22, 0x3b17, 0xf7bc,
    0x0df3, 0x3333, 0x0df3, 0xf7bc, 0x3b17, 0x5e22, 0x0000, 0xa1de,
    0xc4e9, 0x0844, 0xf20d, 0xcccd, 0xf20d, 0x0844, 0xc4e9, 0xa1de
};

static q15_t ref_result[FIR_SIZE] = {
    0x0000, 0x0000, 0x0019, 0x0043, 0x006a, 0x0078, 0x003d, 0xff7a,
    0xfe41, 0xfd23, 0xfd06, 0xfec8, 0x02e8, 0x092e, 0x108d, 0x1779,
    0x1cb9, 0x1ff5, 0x2193, 0x2225, 0x21ea, 0x207f, 0x1cec, 0x1641,
    0x0c68, 0x0078, 0xf43e, 0xe97c, 0xe16e, 0xdca3, 0xdb1b, 0xdca3,
    0xe154, 0xe938, 0xf3d4, 0x0000, 0x0c2b, 0x16c7, 0x1eab, 0x235c,
    0x24e4, 0x235c, 0x1eab, 0x16c7, 0x0c2b, 0x0000, 0xf3d4, 0xe938,
    0xe154, 0xdca3, 0xdb1b, 0xdca3, 0xe154, 0xe938, 0xf3d4, 0x0000,
    0x0c2b, 0x16c7, 0x1eab, 0x235c, 0x24e4, 0x235c, 0x1eab, 0x16c7,
    0x0c2b, 0x0000, 0xf3d4, 0xe938, 0xe154, 0xdca3, 0xdb1b, 0xdca3,
    0xe154, 0xe938, 0xf3d4, 0x0000, 0x0c2b, 0x16c7, 0x1eab, 0x235c,
    0x24e4, 0x235c, 0x1eab, 0x16c7, 0x0c2b, 0x0000, 0xf3d4, 0xe938,
    0xe154, 0xdca3, 0xdb1b, 0xdca3, 0xe154, 0xe938, 0xf3d4, 0x0000,
    0x0c2b, 0x16c7, 0x1eab, 0x235c, 0x24e4, 0x235c, 0x1eab, 0x16c7,
    0x0c2b, 0x0000, 0xf3d4, 0xe938, 0xe154, 0xdca3, 0xdb1b, 0xdca3,
    0xe154, 0xe938, 0xf3d4, 0x0000, 0x0c2b, 0x16c7, 0x1eab, 0x235c,
    0x24e4, 0x235c, 0x1eab, 0x16c7, 0x0c2b, 0x0000, 0xf3d4, 0xe938,
    0xe154, 0xdca3, 0xdb1b, 0xdca3, 0xe154, 0xe938, 0xf3d4, 0x0000,
    0x0c2b, 0x16c7, 0x1eab, 0x235c, 0x24e4, 0x235c, 0x1eab, 0x16c7,
    0x0c2b, 0x0000, 0xf3d4, 0xe938, 0xe154, 0xdca3, 0xdb1b, 0xdca3,
    0xe154, 0xe938, 0xf3d4, 0x0000, 0x0c2b, 0x16c7, 0x1eab, 0x235c,
    0x24e4, 0x235c, 0x1eab, 0x16c7, 0x0c2b, 0x0000, 0xf3d4, 0xe938,
    0xe154, 0xdca3, 0xdb1b, 0xdca3, 0xe154, 0xe938, 0xf3d4, 0x0000,
    0x0c2b, 0x16c7, 0x1eab, 0x235c, 0x24e4, 0x235c, 0x1eab, 0x16c7,
    0x0c2b, 0x0000, 0xf3d4, 0xe938, 0xe154, 0xdca3, 0xdb1b, 0xdca3,
    0xe154, 0xe938, 0xf3d4, 0x0000, 0x0c2b, 0x16c7, 0x1eab, 0x235c,
    0x24e4, 0x235c, 0x1eab, 0x16c7, 0x0c2b, 0x0000, 0xf3d4, 0xe938,
    0xe154, 0xdca3, 0xdb1b, 0xdca3, 0xe154, 0xe938, 0xf3d4, 0x0000,
    0x0c2b, 0x16c7, 0x1eab, 0x235c, 0x24e4, 0x235c, 0x1eab, 0x16c7,
    0x0c2b, 0x0000, 0xf3d4, 0xe938, 0xe154, 0xdca3, 0xdb1b, 0xdca3,
    0xe154, 0xe938, 0xf3d4, 0x0000, 0x0c2b, 0x16c7, 0x1eab, 0x235c,
    0x24e4, 0x235c, 0x1eab, 0x16c7, 0x0c2b, 0x0000, 0xf3d4, 0xe938,
    0xe154, 0xdca3, 0xdb1b, 0xdca3, 0xe154, 0xe938, 0xf3d4, 0x0000,
    0x0c2b, 0x16c7, 0x1eab, 0x235c, 0x24e4, 0x235c, 0x1eab, 0x16c7,
    0x0c2b, 0x0000, 0xf3d4, 0xe938, 0xe154, 0xdca3, 0xdb1b, 0xdca3,
    0xe154, 0xe938, 0xf3d4, 0x0000, 0x0c2b, 0x16c7, 0x1eab, 0x235c,
    0x24e4, 0x235c, 0x1eab, 0x16c7, 0x0c2b, 0x0000, 0xf3d4, 0xe938,
    0xe154, 0xdca3, 0xdb1b, 0xdca3, 0xe154, 0xe938, 0xf3d4, 0x0000,
    0x0c2b, 0x16c7, 0x1eab, 0x235c, 0x24e4, 0x235c, 0x1eab, 0x16c7,
    0x0c2b, 0x0000, 0xf3d4, 0xe938, 0xe154, 0xdca3, 0xdb1b, 0xdca3,
    0xe154, 0xe938, 0xf3d4, 0x0000, 0x0c2b, 0x16c7, 0x1eab, 0x235c
};

static q15_t fir_coeffs[FIR_SIZE] = {
    0x0023, 0x0046, 0x0068, 0x0064, 0x0000, 0xff19, 0xfde3, 0xfd05,
    0xfd71, 0x0000, 0x04f0, 0x0b97, 0x1272, 0x179d, 0x1989, 0x179d,
    0x1272, 0x0b97, 0x04f0, 0x0000, 0xfd71, 0xfd05, 0xfde3, 0xff19,
    0x0000, 0x0064, 0x0068, 0x0046, 0x0023
};

static q15_t fir_states[FIR_SIZE * 2];
static q15_t result[FIR_SIZE * 2];
int main(void)
{
    uint16_t tap;
    uint16_t block_size;
    csi_fir_instance_q15 S;
    int i;

    tap = TAP_NUM + 2;
    block_size = FIR_SIZE;

    csi_fir_init_q15(&S, tap, fir_coeffs, fir_states, block_size);

    csi_fir_q15(&S, src, result, block_size);

    for (i = 0; i < block_size; i++) {
        if (result[i] != ref_result[i]) {
            printf("Example run failed!\r\n");
            while (1)
                ;
        }
    }

    printf("Example run successfully!\r\n");

    return 0;
}
